const Koa = require('koa')
const app = new Koa()

const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const {logger, accessLogger} = require('./logger');

const work = require("./service/jd").default


Object.defineProperty(Array.prototype, "asyncForEach", {
    async value(filter) {
        var ret = 0;
        if (!this.length || !filter) return ret;

        for (var i = 0, len = this.length; i < len; i++) {
            var item = this[i];
            var ret = await filter(item, i);
            if (ret === false) {
                return ret;
            }
            ret++;
        }
        return ret;
    }, enumerable: false
});

global.getFunctionInfo = (a, b) => {
    var start = 2, line = 5;
    if (a && b) {
        start = a;
        line = b;
    } else if (a) {
        line = a;
    }

    try {
        throw new Error("");
    } catch (err) {
        return (err.stack.split("\n").slice(start, lines + start) || []).map(it => {
            //    at D:\code\edu_report\nodejs_score\routes\index.js:172:20
            var line = it.trim();
            if (line.startsWith("at ")) {
                var index1 = line.lastIndexOf(":");
                var index0 = line.lastIndexOf(":", index1 - 1);
                if (index0 > 0 && index1 > 0) {
                    return {
                        file: line.slice(3, index0),
                        line: line.slice(index0 + 1, index1),
                        column: line.slice(index1 + 1)
                    }
                }
            }

            return {file: line}
        })

    }
};



work();

// error handler
onerror(app)

// middlewares
app.use(bodyparser({
    enableTypes: ['json', 'form', 'text']
}));

app.use(json())
// app.use(accessLogger())


// logger
app.use(async (ctx, next) => {

    ctx.error = msg => {
        throw new Error(msg);
    };

    const start = new Date()
    await next()
    if (ctx.res.statusCode != 500) {
        const ms = new Date() - start
        logger.info(`${ctx.res.statusCode} ${ctx.method} ${ctx.url} - ${ms}ms`)
    }
});


let route = require("./routes");

route.init(app);

// error-handling
app.on('error', (err, ctx) => {
    global.score_working_start = null;
    ctx.res.writeHead(500, {
        'content-Type': 'application/json'
    });
    logger.error(`${ctx.res.statusCode} ${ctx.method} ${ctx.url} ${err.message} ${err.stack}`);
    ctx.res.end(JSON.stringify({msg: err.message}));
});

module.exports = app
